﻿using Sunny.Lib;
using Sunny.Lib.CustomeAttribute;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Sunny.Lib.Test
{
    /// <summary>
    ///This is a test class for MiscHelperTest and is intended
    ///to contain all MiscHelperTest Unit Tests
    ///</summary>
    [TestClass()]
    public class MiscHelperTest
    {

        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion


        /// <summary>
        ///A test for EntityToModel
        ///</summary>
        public void ModelToEntityTestHelper<E, M>()
            where E : new()
            where M : new()
        {
            DBContext dbContext = new DBContext();
            var list = (from p in dbContext.Blogs
                        select ConvertHelper.EntityToModel<PostBlog, PostBlogVM>(p)).ToList();

            foreach (var blog in list)
            {
                PostBlog entity = new PostBlog();
                ConvertHelper.ModelToEntity(blog, entity);
            }
        }

        [TestMethod()]
        public void ModelToEntityTest()
        {
            ModelToEntityTestHelper<GenericParameterHelper, GenericParameterHelper>();
        }

        /// <summary>
        ///A test for EntityToModelWithComplexProperty
        ///</summary>
        public void ModelToEntityWithComplexPropertyTestHelper<E, M>()
        {
            DBContext dbContext = new DBContext();
            var list = (from p in dbContext.Blogs
                        select ConvertHelper.EntityToModelWithComplexProperty<PostBlog, PostBlogVM>(p)).ToList();

            foreach (var blog in list)
            {
                PostBlog entity = new PostBlog();
                ConvertHelper.ModelToEntityWithComplexProperty(blog, entity);

                PostBlog entityOld = (from p in dbContext.Blogs where p.SysId ==blog.Id select p).First ();
                bool changed = false;
                string content = ConvertHelper.GetDiff(entityOld, entity, out changed);
            }
        }

        [TestMethod()]
        public void ModelToEntityWithComplexPropertyTest()
        {
            ModelToEntityWithComplexPropertyTestHelper<GenericParameterHelper, GenericParameterHelper>();
        }
    }

    public class DBContext
    {
        public IList<PostBlog> Blogs = new List<PostBlog>();
        public IList<PostBlogComment> Comments = new List<PostBlogComment>();
        public IList<User> Users = new List<User>();

        public DBContext()
        {
            Users.Add(new User { SysId = 1, UserName = "张三", Sex = "男" });
            Users.Add(new User { SysId = 2, UserName = "李四", Age = 20, Sex = "男" });
            Users.Add(new User { SysId = 3, UserName = "王五", Age = 10, Sex = "男" });
            Users.Add(new User { SysId = 4, UserName = "王丽", Age = 35, Sex = "女" });
            Users.Add(new User { SysId = 5, UserName = "薛飞", Age = 31, Sex = "女" });

            Blogs.Add(new PostBlog { SysId = 1, Title = "MVC", Content = "深入浅出MVC", UserId = 1 });
            Blogs.Add(new PostBlog { SysId = 2, Title = "开机启动", Content = "开机启动", UserId = 2, PostDT = DateTime.Now });

            Comments.Add(new PostBlogComment() { SysId = 1, UserId = 2, BlogId = 1, CommentContent = "沙发", CommentDT = DateTime.Parse("2012-12-14 15:09:13") });
            Comments.Add(new PostBlogComment() { SysId = 2, UserId = 3, BlogId = 1, CommentContent = "凳子", CommentDT = DateTime.Parse("2012-12-14 15:09:13") });
            Comments.Add(new PostBlogComment() { SysId = 3, UserId = 4, BlogId = 1, CommentContent = "写的不错", CommentDT = DateTime.Parse("2012-12-14 15:09:13") });
            Comments.Add(new PostBlogComment() { SysId = 4, UserId = 1, BlogId = 1, CommentContent = "谢谢，常来", CommentDT = DateTime.Parse("2012-12-14 15:09:13") });
            Comments.Add(new PostBlogComment() { SysId = 5, UserId = 1, BlogId = 2, CommentContent = "收藏", CommentDT = DateTime.Parse("2012-12-14 15:09:13") });
            Comments.Add(new PostBlogComment() { SysId = 6, UserId = 3, BlogId = 2, CommentContent = "收藏", CommentDT = DateTime.Parse("2012-12-14 15:09:13") });
            Comments.Add(new PostBlogComment() { SysId = 7, UserId = 4, BlogId = 2, CommentContent = "收藏", CommentDT = DateTime.Parse("2012-12-14 15:09:13") });
            Comments.Add(new PostBlogComment() { SysId = 8, UserId = 5, BlogId = 2, CommentContent = "很好", CommentDT = DateTime.Parse("2012-12-14 15:09:13") });
            Comments.Add(new PostBlogComment() { SysId = 9, UserId = 5, BlogId = 2, CommentContent = "很不错", CommentDT = DateTime.Parse("2012-12-14 15:09:13") });

            Blogs.ToList().ForEach(p => {
                p.BlogOwner = Users.Where(u=>u.SysId==p.UserId).FirstOrDefault();
                p.Comments = Comments.Where(c => c.BlogId == p.SysId).ToList();
            });

            Comments.ToList().ForEach(p =>
            {
                p.CommentOwner = Users.Where(u=>u.SysId==p.UserId).FirstOrDefault();
                p.Blog = Blogs.Where(b => p.BlogId == b.SysId).FirstOrDefault();
            });
        }
    }

    public class PostBlog
    {
        public int SysId { get; set; }
        public int UserId { get; set; }
        public string Title { get; set; }
        public string Content { get; set; }
        public DateTime? PostDT { get; set; }
        public bool? Deleted { get; set; }

        public User BlogOwner { get; set; }
        public IList<PostBlogComment> Comments { get; set; }
    }

    public class PostBlogComment
    {
        public int SysId { get; set; }
        public int UserId { get; set; }
        public int BlogId { get; set; }
        public string CommentContent { get; set; }
        public DateTime CommentDT { get; set; }

        public User CommentOwner { get; set; }
        public PostBlog Blog { get; set; }
    }

    public class User
    {
        public int SysId { get; set; }
        public string UserName { get; set; }
        public string Sex { get; set; }
        public int? Age { get; set; }
    }

    public class PostBlogVM
    {
        [ColumnName("sysid")]
        public int Id { get; set; }
        public int UserId { get; set; }
        public string UserName { get; set; }
        public string Title { get; set; }
        public string Content { get; set; }
        public DateTime? PostDT { get; set; }
        public bool? Deleted { get; set; }

        public UserVM BlogOwner { get; set; }
        public IList<PostBlogCommentVM> Comments { get; set; }
    }

    public class PostBlogCommentVM
    {
        [ColumnName("sysid")]
        public int Id { get; set; }
        public int UserId { get; set; }
        public string UserName { get; set; }
        public int BlogId { get; set; }
        public string CommentContent { get; set; }
        public DateTime CommentDT { get; set; }

        public UserVM CommentOwner { get; set; }
        public PostBlogVM Blog { get; set; }
    }

    public class UserVM
    {
        [ColumnName("sysid")]
        public int Id { get; set; }
        public string UserName { get; set; }
        public string Sex { get; set; }
        public int? Age { get; set; }
    }
}
